/**
 * 
 */
package br.srv.full.postalservices.faces.components.renderer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.ConverterException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import br.srv.full.faces.utils.FacesRendererUtils;
import br.srv.full.geoProcessing.entities.localidades.Locale;
import br.srv.full.geoProcessing.entities.localidades.LocaleType;

/**
 * @author Carlos Delfino
 * 
 */
public class HTMLLocaleRenderer extends  javax.faces.render.Renderer {

	private final Log log = LogFactory.getLog(getClass());

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext,
	 *      javax.faces.component.UIComponent)
	 */
	@Override
	public void decode(FacesContext p_context, UIComponent p_component) {
		super.decode(p_context, p_component);
		// TODO Auto-generated method stub
		log.info(p_context);
		log.info(p_component);

		FacesRendererUtils.rendererParamsNotNull(p_context, p_component);

		if (!FacesRendererUtils.shouldDecode(p_component)) {
			return;
		}

		String clientId = p_component.getClientId(p_context);
		assert (clientId != null);
		Map<String, String> requestMap = p_context.getExternalContext().getRequestParameterMap();
		// Don't overwrite the value unless you have to!
		
		// aqui deve obter cada valor e reconstruir o objeto.
		String newValue = requestMap.get(clientId);
		if (newValue != null) {

			if (log.isInfoEnabled()) {
				log.info(String.format("new value after decoding {0}", newValue));
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext,
	 *      javax.faces.component.UIComponent)
	 */
	@Override
	public void encodeBegin(FacesContext p_context, UIComponent p_component) throws IOException {
		// TODO Auto-generated method stub
		super.encodeBegin(p_context, p_component);

		ResponseWriter l_rw = p_context.getResponseWriter();
		assert (l_rw != null);

		l_rw.startElement(FacesRendererUtils.DIV_TAG, p_component);
		FacesRendererUtils.encodeIdAndNameAttribute(p_context, p_component);

		FacesRendererUtils.encodeHeaderFacet(p_context, p_component);

		l_rw.startElement(FacesRendererUtils.TABLE_TAG, p_component);
		FacesRendererUtils.encodeIdAndNameAttribute(p_context, p_component, "table");

		boolean l_useTable = true;
		encodeTypesLocaleSelect(p_context, p_component, l_useTable);

		encodeInputLocaleAcronym(p_context, p_component, l_useTable);

		encodeInputLocaleName(p_context, p_component, l_useTable);

		encodeSuperLocales(p_context, p_component, l_useTable);

		l_rw.endElement(FacesRendererUtils.TABLE_TAG);

		FacesRendererUtils.encodeBottonFacet(p_context, p_component);

		l_rw.endElement(FacesRendererUtils.DIV_TAG);
	}

	/**
	 * @param p_context
	 * @param p_component
	 * @param p_table
	 * @param l_rw
	 * @throws IOException
	 */
	private void encodeInputLocaleName(FacesContext p_context, UIComponent p_component, boolean p_table)
			throws IOException {
		ResponseWriter l_rw = p_context.getResponseWriter();
		String l_currentValue;
		if (!p_table) {
			l_rw.startElement(FacesRendererUtils.TR_TAG, p_component);
			l_rw.startElement(FacesRendererUtils.TD_TAG, p_component);
		}
		/*
		 * constroi o componente HTML que exibe o nome!
		 */
		l_currentValue = null;
		l_currentValue = (l_currentValue == null ? "name" : l_currentValue);
		FacesRendererUtils.encodeTextWithLabelToRender(p_context, p_component, "name", "Name: ", l_currentValue,
				p_table);
		if (!p_table) {
			l_rw.endElement(FacesRendererUtils.TD_TAG);
			l_rw.endElement(FacesRendererUtils.TR_TAG);
		}
	}

	/**
	 * * constroi o componente HTML que exibe a sigla!
	 * 
	 * @param p_context
	 * @param p_component
	 * @param p_table
	 * @param l_rw
	 * @throws IOException
	 */
	private void encodeInputLocaleAcronym(FacesContext p_context, UIComponent p_component, boolean p_table)
			throws IOException {
		ResponseWriter l_rw = p_context.getResponseWriter();
		if (!p_table) {
			l_rw.startElement(FacesRendererUtils.TR_TAG, p_component);
			l_rw.startElement(FacesRendererUtils.TD_TAG, p_component);
		}
		String l_currentValue = null;
		l_currentValue = (l_currentValue == null ? "acronym" : l_currentValue);
		FacesRendererUtils.encodeTextWithLabelToRender(p_context, p_component, "acronym", "Acronym:", l_currentValue,
				p_table);
		if (!p_table) {
			l_rw.endElement(FacesRendererUtils.TD_TAG);
			l_rw.endElement(FacesRendererUtils.TR_TAG);
		}
	}

	/**
	 * @param p_context
	 * @param p_component
	 * @param p_table
	 * @param l_rw
	 * @throws IOException
	 */
	private void encodeSuperLocales(FacesContext p_context, UIComponent p_component, boolean p_table)
			throws IOException {
		ResponseWriter l_rw = p_context.getResponseWriter();
		if (!p_table) {
			l_rw.startElement(FacesRendererUtils.TR_TAG, p_component);
			l_rw.startElement(FacesRendererUtils.TD_TAG, p_component);
		}
		List<Locale> l_superLocales = getSuperLocales(p_context, p_component);

		Object l_selected = null;
		String l_acronym = p_context.getELContext().getLocale().getCountry();
		for (Locale l_locale : l_superLocales) {
			l_selected = l_locale;
			if (l_locale.getAcronym().equals(l_acronym))
				break;
		}
		if (l_selected == null)
			l_selected = l_superLocales.get(Math.max(l_superLocales.size() / 2, 1));

		FacesRendererUtils.encodeSelectWithLabelToRender(p_context, p_component, "superLocaleList", "Pertence a:",
				l_superLocales, l_selected, p_table);

		if (!p_table) {
			l_rw.endElement(FacesRendererUtils.TD_TAG);
			l_rw.endElement(FacesRendererUtils.TR_TAG);
		}
	}

	/**
	 * @param p_context
	 * @param p_component
	 * @param p_useTable
	 * @param l_rw
	 * @throws IOException
	 */
	private void encodeTypesLocaleSelect(FacesContext p_context, UIComponent p_component, boolean p_useTable)
			throws IOException {
		ResponseWriter l_rw = p_context.getResponseWriter();
		if (!p_useTable) {
			l_rw.startElement(FacesRendererUtils.TR_TAG, p_component);
			l_rw.startElement(FacesRendererUtils.TD_TAG, p_component);
		}

		List<LocaleType> l_typesLocale = getTypesLocale(p_context, p_component);
		Object l_selected = l_typesLocale.get(l_typesLocale.size() - 1);
		FacesRendererUtils.encodeSelectWithLabelToRender(p_context, p_component, "typeLocaleList", "Tipo:",
				l_typesLocale, l_selected, p_useTable);
		if (!p_useTable) {
			l_rw.endElement(FacesRendererUtils.TD_TAG);
			l_rw.endElement(FacesRendererUtils.TR_TAG);
		}
	}

	/**
	 * @param p_context
	 * @param p_component
	 * @return
	 */
	private List<LocaleType> getTypesLocale(FacesContext p_context, UIComponent p_component) {
		List<LocaleType> l_locales = new ArrayList<LocaleType>();
		LocaleType l_ctr = new LocaleType("ctr", "Country");
		l_locales.add(l_ctr);

		LocaleType l_stt = new LocaleType("stt", "State");
		l_locales.add(l_stt);

		LocaleType l_cty = new LocaleType("cty", "City");
		l_cty.add(l_stt);

		l_locales.add(l_cty);

		LocaleType l_mnc = new LocaleType("mnc", "Municipio");
		l_mnc.add(l_stt);

		l_locales.add(l_mnc);

		LocaleType l_vle = new LocaleType("vle", "ville");
		l_vle.add(l_cty);
		l_vle.add(l_mnc);

		l_locales.add(l_vle);

		LocaleType l_rgn = new LocaleType("rgn", "Region");
		l_vle.add(l_ctr);
		l_vle.add(l_cty);
		l_vle.add(l_mnc);
		l_vle.add(l_rgn);

		l_locales.add(l_rgn);

		// TODO Auto-generated method stub
		return l_locales;
	}

	/**
	 * @param p_context
	 * @param p_component
	 * @return
	 */
	private List<Locale> getSuperLocales(FacesContext p_context, UIComponent p_component) {
		List<Locale> l_locales = new ArrayList<Locale>();
		LocaleType l_otr = new LocaleType("otr", "Others");
		l_locales.add(new Locale(l_otr, "  ", " "));

		LocaleType l_ctr = new LocaleType("ctr", "Country");

		l_locales.add(new Locale(l_ctr, "BR", "Brasil"));
		l_locales.add(new Locale(l_ctr, "US", "Estados Unidos"));

		// TODO Auto-generated method stub
		return l_locales;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.faces.render.Renderer#getConvertedValue(javax.faces.context.FacesContext,
	 *      javax.faces.component.UIComponent, java.lang.Object)
	 */
	@Override
	public Object getConvertedValue(FacesContext p_context, UIComponent p_component, Object p_submittedValue)
			throws ConverterException {
		log.info(p_context);
		log.info(p_component);
		log.info(p_submittedValue);
		// TODO Auto-generated method stub
		return super.getConvertedValue(p_context, p_component, p_submittedValue);
	}

	/**
	 * 
	 */
	public HTMLLocaleRenderer() {
		super();
		// TODO Auto-generated constructor stub
		log.info("instantiate");
	}
}